
\chapter{饿了么JDBC项目}
本项目为软件工程综合实践课程的第一个项目。要求使用 javaSE + JDBC + MySql 技术开发
基于控制台的C/S结构应用程序。


\section{需求分析}\label{section:xuqiufenxi}

\subsection{简介}

本项目是软件工程综合实践课程中的第一个任务。
根据智慧树平台上的项目任务书，我们要开发一个控制台程序，用于管理数据库中的相关表项。
随后的几个项目将涉及外卖平台的点餐业务流程，
因此本项目需要实现商家和管理员这两个角色分别通过各自的管理程序登录，
并管理与自己相关的表项。
\subsubsection{背景}
外卖平台上的业务的运作主要涉及到这些角色：
\begin{enumerate}[label={(\arabic*)}]
    \item 客户：消费者，在平台上选择商家和该商家的食品并下单付款，最终收到骑手送来的食品
    \item 商家：生产者，在平台上管理自己的店铺和食品的信息，接受客户发来的订单并制作食品，等待
    骑手前来取餐。最终获取客户付的钱款的一部分
    \item 骑手：负责将食品从商家配送至客户，本项目中假设商家需自行雇人配送
    \item 平台管理员：负责与商家交涉，在平台数据库中添加和删除商家
\end{enumerate}

商家和平台管理员是本项目中两个关键角色，他们与平台的后台管理密切相关。管理员负责商家管理，而商家则负责自我管理。
因此，本项目的解决方案涉及以下两个方面的问题：
\begin{enumerate}[label={(\arabic*)}]
    \item 管理员通过管理员入口登录，添加和删除商家
    \item 商家通过商家入口登录，管理自己的店铺信息和食品列表。
\end{enumerate}
管理员负责添加和删除商家；只有被添加的商家才能够管理自己的店铺信息和食品列表。

\subsubsection{约束}
本项目因为是课程教学项目，所以对编程语言、平台和工具都有一定的要求，结合上文中关于项目功能方面的要求，本项目应该具有以下约束：
\begin{itemize}
    \item 数据库使用MySQL数据库
    \item 开发语言使用JAVASE 1.8
    \item 使用JDBC(mysql-connector-java)实现数据库的管理
    \item 管理员通过数据库管理工具执行SQL语句添加
    \item 商家只能由管理员添加和删除
    \item 管理员和商家都需要输入正确的用户名和密码来登录管理系统
    \item 项目可扩展，具备经过少量改造就可以跟后续项目的数据库对接的潜力
\end{itemize}

\subsection{项目目标、涉众分析和范围}
\subsubsection{目标}
\begin{itemize}
    \item 实现外卖平台中管理员的登录、查看、添加、删除商家的业务
    \item 实现外卖平台中商家的登录，管理店铺信息，增减商品等基本业务
\end{itemize}

\subsubsection{涉众分析}
本项目设计到的三个角色，用添加删除权限的关系可以绘制出以下的组织图。

以下是本项目的涉众分析表：

\begin{table}[htbp]
    \centering
    \caption{项目涉众分析表}
    \footnotesize
    \begin{tabular}{|c|c|c|}
    \hline
    序号 & 涉众     & 待解决问题/对系统的期望                                                                                                                                                                            \\ \hline
    1  & 数据库管理员 & 通过简单的SQL语句利用数据库管理工具管理平台管理员                                                                                                                                                              \\ \hline
    2  & 平台管理员  & \begin{tabular}[c]{@{}l@{}}1. 拥有自己的管理员编号和密码，可以通过用户名和密码登录系统   \\ 2. 系统能够判断输入编号和密码是否正确，防止他人登录自己的账户   \\ 3. 系统能够列出所有商家，方便自己快速查看浏览    \\ 4. 能够添加、删除商家    \\ 5. 能够通过输入商家名搜索商家\end{tabular} \\ \hline
    3  & 商家     & \begin{tabular}[c]{@{}l@{}}1.拥有自己的商家编号和密码，可以通过用户名和密码登录系统 \\ 2. 系统能够判断输入编号和密码是否正确，防止他人登录自己的账户\\ 3. 能够查看和修改店铺的基本信息，登录密码\\ 4. 能够查看食品列表\\  5. 能够添加、修改和删除食品\end{tabular}                 \\ \hline
    \end{tabular}
    \end{table}

\subsubsection{范围}
本项目要求经过少量修改后可以跟本课程的项目三、四的数据库对接，
能够完成商家、管理员、食品三个表的管理。

\subsection{业务流程分析}
本项目设计的业务主要有新商家的注册、商家的删除、商家管理店铺信息和食品列表。
以下给出这三个主要业务的活动图和状态图。
\subsubsection{新商家的注册}


\subsubsection{商家的删除}
此业务只涉及平台管理员。较为简单，所以只给出活动图。


\subsubsection{商家管理店铺信息}
此业务只涉及商家这一个角色，所以只给出活动图。


\subsubsection{商家管理食品列表}
食品管理业务应该有五个选项，这五个选项分别是:
\begin{itemize}
    \item 查看食品列表：列出属于这个商家的所有食品
    \item 新增食品：提示商家输入食品的各个信息，完成新增
    \item 修改食品：提示商家输入修改的食品编号和修改后的食品信息，完成修改
    \item 删除食品：提示商家输入食品编号，完成删除
    \item 退出食品管理：退出系统或退回上一级菜单
\end{itemize}




\subsection{功能需求}





需要补充说明的是，管理员和商家都需要登录才可以进行后续的操作。因此每一个商家和管理员都需要一个唯一的Id和对应的密码。

总的来说，需求都可以归为对数据库的查询和更改这两种操作：


\begin{itemize}
    \item[$\bullet$] 数据查询：列出所有商家、搜索商家、查看商家信息和查看食品列表。
    \item[$\bullet$] 数据库更改：新建商家、删除商家、修改商家信息、更改密码、新增食品、修改食品和删除食品。
\end{itemize}

因此，我们需要设计一套接口来操作数据库中的多个表。考虑到功能要求相对简单，我们可以采用简单的C/S架构，将项目分为两层。
上层负责与用户进行交互，引导用户以获取符合要求的输入，并将用户的操作进行分类后调用下层的接口；下层则负责接收上层的请求，并执行相应的数据库操作。

\subsection{非功能性需求}
\subsubsection{系统架构和工具}
\begin{itemize}
    \item 项目要求采用C/S架构
    \item 编程语言：java
    \item 数据库：MySQL
    \item 要求使用JDBC完成数据库事务管理
\end{itemize}
\subsubsection{接口}
对接口没有硬性要求，风格良好即可。
\subsubsection{界面}
本项目要求开发控制台应用程序，美观界面的实现难度较大，业务流程清晰简洁，
程序输出整齐、可读性良好即可。



\section{软件架构与设计}
根据需求分析结果，本项目的难点是设计并实现一个操作数据库中若干表的接口。与用户交互的部分也是无需设计窗体界面，只需要实现控制台上的简单交互即可。
\subsection{软件架构}
在本项目中，我们选择了C/S架构来设计一个后台管理系统。在实际开发中，
我们采用了两层的分层架构，分别是视图层（View层）和数据持久层（Dao层），这两层分别对应客户端和服务端。


分为上述的两层既可以提高效率，又比较符合我们团队的规模。采用前后端的开发形式可以进行有效的分工，提高开发效率。

\subsection{软件设计}
\subsubsection{数据库设计}
我们选择了MySQL数据库8.0.28版本作为数据库。通过编写SQL脚本，我们创建了数据库和表，并导入了一些测试数据。我们使用Navicat 16 for MySQL来查看和管理数据库。

根据需求分析，我们设计了三个数据库表：商家表（Business）、食品表（Food）和管理员表（Admin）。接下来，我们将分别给出这三个表的结构。约定的约束类型标识如下：
\begin{itemize}
    \item[$\bullet$] PK: 主键约束(primary key)
    \item[$\bullet$] FK: 外键约束(foreign key)
    \item[$\bullet$] NN: 非空约束(not null)
    \item[$\bullet$] UQ: 唯一约束(unique)
    \item[$\bullet$] AI: 自增约束(auto increment)
\end{itemize}


商家可以通过系统分配给他们的唯一号码和自行设定的密码来登录系统。商家的添加是由管理员完成的，管理员只需提供商家的密码和名称，无需提供其他信息。

一旦商家被添加到商家表中，他们就可以通过商家入口登录系统，并进一步修改自己的其他信息。

\begin{table}[htbp]
    \centering
    \caption{商家表(Business)}\label{BusinessTable}
    \begin{tabular}{|c|c|c|c|c|c|}
        \toprule[1.5pt]

        字段名        & 数据类型 & 大小  & 默认值 & 约束                 & 说明                                           \\
        \hline

        id            & int      &       &        & \footnotesize PK、AI & \scriptsize 商家编号，同时也是商家的登录用户名 \\
        \hline
        password      & varchar  & 20    &        & NN                   & 商家的登陆密码                                 \\
        \hline
        Name          & varchar  & 40    &        & NN                   & 商家名称                                       \\
        \hline
        Address       & varchar  & 100   &        &                      & 商家地址                                       \\
        \hline
        Explain       & varchar  & 40    &        &                      & 商家的介绍                                     \\
        \hline
        starPrice     & decimal  & (5,2) & 0.00   &                      & 起送费                                         \\
        \hline
        deliveryPrice & decimal  & (5,2) & 0.00   &                      & 配送                                           \\

        \bottomrule
    \end{tabular}
\end{table}

食品是商家添加的。商家需要提供食品的名称、介绍、价格便可以在食品表里新增一个食品。食品有所属商家编号这一属性，代表着一个食品
有且仅有一个商家与之对应。



\begin{table}[htbp]
    \centering
    \caption{食品表(Food)}\label{FoodTable}
    \begin{tabular}{|c|c|c|c|c|c|}
        \toprule
        字段名     & 数据类型 & 大小  & 默认值 & 约束   & 说明           \\
        \midrule
        id         & int      &       &        & PK、AI & 食品编号       \\
        \hline
        name       & varchar  & 30    &        & NN     & 食品名称       \\
        \hline
        explain    & varchar  & 100   &        &        & 食品介绍       \\
        \hline
        price      & decimal  & (5,2) &        & NN     & 食品价格       \\
        \hline
        businessId & int      &       &        & FK、NN & 所述商家的编号 \\
        \bottomrule
    \end{tabular}
\end{table}

管理员是通过数据库管理工具往数据库中添加的。管理员通过编号和密码登录系统后就可以新建商家和删除商家。



\begin{table}[htbp]
    \centering
    \caption{管理员表(Admin)}\label{AdminTable}
    \begin{tabular}{|c|c|c|c|c|c|}
        \toprule
        字段名   & 数据类型 & 大小 & 默认值 & 约束   & 说明                                               \\
        \midrule
        id       & int      &      &        & PK、AI & \scriptsize 管理员编号，同时也是管理员的登录用户名 \\
        \hline
        name     & varchar  & 20   &        & NN、UQ & 管理员名称                                         \\
        \hline
        password & varchar  & 20   &        & NN     & 登录密码                                           \\
        \bottomrule
    \end{tabular}
\end{table}


\subsubsection{接口设计}\label{section:jiekousheji}
由于我们采用了View层和Dao层的分离开发，所以Dao层必须提供相关的接口。我们设计了四个接口，分别对应数据库中的四张表，并为每个接口提供了相应的实现。


接下来给出每一个接口方法的作用、参数和返回值。


\begin{table}[htbp]
    \centering
    \caption{BusinessDao接口方法详解}\label{BusinessInterfaceTable}

    \tiny
    \begin{tabular}{|l|l|l|l|l|}
        \hline
        方法名 & 作用                                                                             & 参数                                                                                                                                                                                             & 返回值                                                                                                                                                        & 异常                         \\ \hline
        get    & \begin{tabular}[c]{@{}l@{}}从数据库中按条件搜索\\商家信息并返回列表\end{tabular} & \begin{tabular}[c]{@{}l@{}}Business类中除了Id之外的所有属性。\\每一个属性均可以为NULL，代表\\查询条件中不包含此属性。对字符\\串属性模糊查询。配送费和起送费返\\回不大于该值的商家。\end{tabular} & \begin{tabular}[c]{@{}l@{}}空List: 数据库中没有匹配的商家\\      非空的List: 数据库中有匹配的商家\\       null: 格式错误或内部错误\end{tabular}               & SQLException; 数据库抛出异常 \\ \hline
        get    & \begin{tabular}[c]{@{}l@{}}通过Id和密码\\  获取Business对象\end{tabular}         & \begin{tabular}[c]{@{}l@{}}Id: Integer\\       password: String\end{tabular}                                                                                                                     & \begin{tabular}[c]{@{}l@{}}Business: Id和密码匹配成功，返回\\对应商家\\       null: 格式错误或内部错误\end{tabular}                                           & SQLException; 数据库抛出异常 \\ \hline
        delete & 删除商家                                                                         & Id: Integer                                                                                                                                                                                      & \begin{tabular}[c]{@{}l@{}}200: 成功删除\\       400: 参数格式错误\\       500: 内部错误\end{tabular}                                                         & SQLException; 数据库抛出异常 \\ \hline
        put    & 新建商家                                                                         & \begin{tabular}[c]{@{}l@{}}Business类中除了Id之外的所有属性。\\其中name和password不可以为null\end{tabular}                                                                                       & \begin{tabular}[c]{@{}l@{}}201: 新建商家成功\\       400: 参数格式错误\\       500: 内部错误\end{tabular}                                                     & SQLException; 数据库抛出异常 \\ \hline
        update & 更新商家信息                                                                     & \begin{tabular}[c]{@{}l@{}}Business类的所有属性。除了Id每一个\\属性均可以为NULL，代表不更新此属\\性。Id属性是为了定位商家，不会被\\修改\end{tabular}                                             & \begin{tabular}[c]{@{}l@{}}201: 更新成功\\       400: 参数格式错误\\       404: 不存在该Id的商家\\       500: 内部错误\end{tabular}                           & SQLException; 数据库抛出异常 \\ \hline
        update & 更新管理员信息                                                                   & \begin{tabular}[c]{@{}l@{}}Id: 管理员编号\\       name: 管理员名称\\       password: 密码\end{tabular}                                                                                           & \begin{tabular}[c]{@{}l@{}}201: 修改成功\\       400: 参数格式错误\\       403: 拒绝修改\\       404: 没有此Id对应的管理员\\       500; 内部错误\end{tabular} & SQLException: 数据库抛出异常 \\ \hline
    \end{tabular}
\end{table}




\begin{table}[htbp]
    \centering
    \caption{FoodDao接口方法详解}\label{FoodInterfaceTable}
    \tiny
    \begin{tabular}{|l|l|l|l|l|}
        \hline
        方法名 & 作用                                                                    & 参数                                                                                                                             & 返回值                                                                                                                         & 异常                         \\ \hline
        get    & \begin{tabular}[c]{@{}l@{}}从数据库中查询\\ 符合条件的食物\end{tabular} & \begin{tabular}[c]{@{}l@{}}Food的所有属性。属性为null代表查\\询条件里没有此属性。minPrice和\\maxPrice是价格的上下限\end{tabular} & \begin{tabular}[c]{@{}l@{}}null: 格式错误、内部错误 \\ 空List: 没有匹配的书屋\\ 非空List: 存在匹配的食物\end{tabular}          & SQLException: 数据库抛出异常 \\ \hline
        put    & 添加食物                                                                & food: Food                                                                                                                       & \begin{tabular}[c]{@{}l@{}}201: 添加成功\\ 400: 参数格式错误\\ 500: 内部错误\end{tabular}                                      & SQLException: 数据库抛出异常 \\ \hline
        put    & 添加食物                                                                & Food除了Id的所有属性                                                                                                             & 同上                                                                                                                           & SQLException: 数据库抛出异常 \\ \hline
        delete & 删除食物                                                                & id: Integer                                                                                                                      & \begin{tabular}[c]{@{}l@{}}200: 删除成功\\ 400: 参数格式错误\\ 404: 不存在此id的食物\\ 500: 内部错误\end{tabular}              & SQLException: 数据库抛出异常 \\ \hline
        update & 更新食物的信息                                                          & \begin{tabular}[c]{@{}l@{}}Food的所有属性。Id用于定位，其余\\属性为null代表不更新\end{tabular}                                   & \begin{tabular}[c]{@{}l@{}}201: 成功修改\\ 400: 参数格式错误\\ 404: 不存在此id的食物\\ \\ 500: 数据库系统内部错误\end{tabular} & SQLException: 数据库抛出异常 \\ \hline
        update & 更新食物的信息                                                          & food: Food                                                                                                                       & 同上                                                                                                                           & SQLException: 数据库抛出异常 \\ \hline
    \end{tabular}
\end{table}


\begin{table}[htbp]
    \caption{AdminDao接口方法详解}\label{AdminDaoInterfaceTable}
    \tiny
    \begin{tabular}{|l|l|l|l|l|}
        \hline
        方法名 & 作用                                                                         & 参数                                                                                                             & 返回值                                                                                                                                                                & 异常                         \\ \hline
        get    & \begin{tabular}[c]{@{}l@{}}通过管理员名称和密码获取管\\理员对象\end{tabular} & \begin{tabular}[c]{@{}l@{}}name: 管理员名称\\       password: 密码\end{tabular}                                  & \begin{tabular}[c]{@{}l@{}}Admin: 找到了用户民和密码都匹配的管理员\\       null: 参数错误、内部错误、未找到匹配的管理员\end{tabular}                                  & SQLException: 数据库抛出异常 \\ \hline
        get    & 获取管理员列表                                                               &                                                                                                                  & \begin{tabular}[c]{@{}l@{}}空List: 数据库管理员表为空\\       非空的List: 数据库管理员列表\\       Null: 内部错误等\end{tabular}                                      & SQLException: 数据库抛出异常 \\ \hline
        put    & 向数据库中添加管理员                                                         & \begin{tabular}[c]{@{}l@{}}name: 管理员名称\\       password: 密码\end{tabular}                                  & \begin{tabular}[c]{@{}l@{}}201: 添加管理员成功\\       400: 参数格式错误\\       409: 管理员名称已存在\\       500; 内部错误\end{tabular}                             & SQLException: 数据库抛出异常 \\ \hline
        delete & 删除管理员                                                                   & Id: 管理员编号                                                                                                   & \begin{tabular}[c]{@{}l@{}}200: 管理员删除成功\\       400: 参数格式错误\\       500: 内部错误\end{tabular}                                                           & SQLException: 数据库抛出异常 \\ \hline
        delete & 用名称和密码删除管理员                                                       & \begin{tabular}[c]{@{}l@{}}name: 管理员名称\\      password: 密码\end{tabular}                                   & \begin{tabular}[c]{@{}l@{}}200: 管理员删除成功\\       400: 参数格式错误\\       403: 管理员密码错误\\       404: 管理员名称不存在\\       500: 内部错误\end{tabular} & SQLException: 数据库抛出异常 \\ \hline
        update & 更新管理员信息                                                               & \begin{tabular}[c]{@{}l@{}}Id: 管理员编号\\            name: 管理员名称\\            password: 密码\end{tabular} & \begin{tabular}[c]{@{}l@{}}201: 修改成功\\       400: 参数格式错误\\       403: 拒绝修改\\       404: 没有此Id对应的管理员\\       500; 内部错误\end{tabular}         & SQLException: 数据库抛出异常 \\ \hline
    \end{tabular}
\end{table}



\section{项目团队与分工}
郑宇轩负责项目整体框架搭建，商家业务流的编写，功能完善，文档编写 

杨乐负责项目整体框架搭建，管理员业务流的编写，功能完善，文档编写 

\section{项目技术}
\subsection{开发环境}
本项目使用javaSE + JDBC + MySql技术进行开发。使用Spring Tool Suite作IDE，项目依赖有：
\begin{itemize}
    \item[$\bullet$] JRE System Libary[JavaSE-1.8]
    \item[$\bullet$] MySql connector 5.1.49
\end{itemize}
\subsection{代码共享}
在本项目中，我们使用GIT进行项目管理，并将远程仓库托管在Gitee上。

远程仓库的地址为：

https://gitee.com/cloudoftwilight/elb.git

为了保持代码同步，我们约定在开始编码之前使用git pull命令来更新代码。
每次完成编码后，使用git commit和git push命令将代码上传至远程仓库。在使用git commit命令时，
需要添加-m选项来提供简要的注释，注释中必须说明该次上传完成了哪个部分，修复了哪个Bug等。


\section{项目部署}
\subsection{开发环境检查}
此部署文档适用于Windows 10(11)操作系统。其他操作系统上一些步骤可能有
细微差别，具体解决方案可求助互联网。

本项目使用Spring tool suite作IDE(以下简称STS)。安装STS后，
需要更改STS的编码配置为UTF-8。部署前需要保证电脑安装了以下工具和软件:
\begin{itemize}
    \item Git
    \item MySQL 8.0以上版本
    \item Spring tool suite 4
    \item Navicat for MySQL 16
    \item JRE 1.8
\end{itemize}

接下来给出后续部署工作的详细步骤。
\subsection{数据库准备工作}
打开cmd或PowerShell，并输入以下命令：

mysql -u root -p

如果MySQL已经正确安装，会提示输入密码。请输入当前root账户的密码，然后输入以下命令：

mysqladmin -u root -p password "123456"

如果出现\textcolor{red}{Query OK, 0 rows affected (0.36 sec)}，表示密码修改成功。

打开Navicat for MySQL 16，并创建一个新的查询。
将智慧树平台上项目一的SQL文件中的内容复制到查询窗口中。点击运行即可创建数据库和其中的三个表。


\subsection{在STS导入并配置项目}
打开STS（Spring Tool Suite），点击左侧的"Import Project"，选择"General"目录下的"Existing Project into Workspace"。

点击"Browse"按钮，选择"elm"目录，然后点击"确定"。接着点击"Finish"按钮即可完成导入。

右键点击项目，选择"Properties"，点击左侧的"Java Build Path"，然后点击"Libraries"。
点击"Add"按钮，选择"mysql-connector-java 5.1.49"进行导入。 接着点击"Apply"按钮进行确认。

通过以上操作，即可完成本项目的部署。



\section{系统的调试与测试}
\subsection{Dao层接口的测试}
对于Dao层的三个接口类的实现，我们编写测试程序分别进行了测试，
检验各种合法输入下能否返回正确的结果，对于错误的输入能否抛出正确的异常和返回正确的状态码。
以下是测试过程：

\begin{itemize} 
    \item[$\bullet$] 第1次测试，AdminDao未通过。经过调试发现SQL语句中有单词拼写有误。
    \item[$\bullet$] 第2次测试，AdminDao未通过。经过调试发现get方法返回的状态码写错了。
    \item[$\bullet$] 第3次测试，FoodDao未通过。经过调试发现delte方法成功后应返回200，但返回了201。
    \item[$\bullet$] 第4次测试，BusinessDao未通过。发现SQL脚本的建表语句中startPrice写成了starPrice
    \item[$\bullet$] 第5次测试，全部测试通过
\end{itemize}

\subsection{View层的测试}
View层的测试主要是通过在控制台界面的各种操作进行。接下来分别给出对商家系统和管理员系统的测试过程和结果。
\subsubsection{管理员系统}
$\bullet$ 登录用户名或密码错误：显示“管理员名称或密码输入错误!”后退出程序。符合预期，测试通过。

$\bullet$ 登录用户名和密码正确：进入操作选择页面，符合预期，测试通过。

$\bullet$ 列出所有商家：控制台中列出来7个商家列表，商家各项信息跟数据库中的数据相符。测试通过

$\bullet$ 搜索商家：商家名称输入“饭”，商家地址输入“阳市”，搜索出三个商家。符合预期，测试通过。

$\bullet$ 新建商家：商家名称输入“扬州炒饭”，密码输入“123”，提示“新建商家成功！商家编号为：10013”。用Navicat查看商家表，看到商家创建成功。
符合预期，测试通过。

$\bullet$ 删除商家：商家编号输入错误的商家编号10014，提示“删除商家失败！”。商家编号输入10013，提示“删除商家成功！”。符合预期，测试通过。

$\bullet$ 输入错误的选项编号：输入9，提示“没有这个选项！”。符合预期，测试通过。

$\bullet$ 退出系统：输入选项5，提示:“欢迎下次光临饿了么后台管理系统”后程序结束。符合预期，测试通过。



\subsubsection{商家系统}
$\bullet$ 登录用户名或密码错误：显示“商家编号或密码输入错误！”后退出程序。符合预期，测试通过。

$\bullet$ 登录用户名和密码正确：进入操作选择页面，符合预期，测试通过。

$\bullet$ 查看商家信息：输入选项编号后，程序输出该商家的各项信息，与数据库相符，测试通过。

$\bullet$ 修改商家信息：商家名称输入“达哥饺馅”，商家地址输入“天津市津南区”，商家介绍输入“好吃不如饺子”，起送费输入20.0，配送费输入3.3。提示
“修改商家信息成功！”。查看数据库，商家各项信息跟数据库中的数据相符，测试通过。

$\bullet$ 修改密码(正常输入)：输入一次旧密码，输入两次新密码，提示“修改密码成功！”。查看数据库里的密码，和新密码相同，测试通过。

$\bullet$ 修改密码(旧密码输入错误)：输入错误的旧密码，提示“旧密码输入错误！”，符合预期，测试通过。

$\bullet$ 修改密码（新密码两次输入不相同）：输入正确的旧密码，新密码两次输入不相同。提示“两次输入密码不一致！”，符合预期，测试通过。

$\bullet$ 进入商品管理页面：输入4，进入了二级菜单。符合预期，测试通过。

$\bullet$ 查看食品列表：程序输出了5个菜品的信息。符合预期，测试通过。

$\bullet$ 新增食品：食物名称输入“驴肉饺子”，食物介绍输入“好吃的驴肉饺子”，价格输入20，程序提示“新增食品成功！”。查看数据库看到数据库
中出现了该食品，测试通过。

$\bullet$ 修改食品(错误的编号)：输入错误的食品编号，提示“没有这个编号的食品.”。符合预期，测试通过。

$\bullet$ 修改食品（正确的编号）：输入正确的编号，名称输入“狗肉饺子”，介绍输入“最好吃的饺子”，价格输入15。程
序提示“修改食品成功！”。查看数据库，看到对应的行被修改，测试通过。

$\bullet$ 删除食品(错误的编号)：输入错误的食品编号，提示“删除食品失败！”。符合预期，测试通过。

$\bullet$ 删除食品(正确的编号)：输入正确的食品编号，提示“删除食品成功！”。查看数据库，看到对应的行被删除，测试通过。

$\bullet$ 输入错误的选项编号：输入9，提示“没有这个选项！”。符合预期，测试通过。

$\bullet$ 返回一级菜单：输入选项的编号，程序抛出异常NoSuchElementException。排查后发现scanner被close之后被再次使用，删除close语句后再次测试，
程序成功返回一级菜单，测试通过。

$\bullet$ 退出系统：输入选项5，提示:“欢迎下次光临饿了么后台管理系统”后程序结束。符合预期，测试通过。


可见，View层不仅对正常输入给出了正确的结果，还可以检测错误的输入并给出响应的提示。经过几次测试和修改，最终的版本通过了所有测试。View层的测试结束。


\section{项目特色}
\subsection{需求分析}
在需求分析阶段，我们认真阅读并学习了《UML大战需求分析》这本书，学习了如何使用UML这一强大的工具来帮助我们快速分析和确定需求，并进行需求建模。

我们参考了该书附录1中的案例，完成了完整的需求分析过程，并撰写了需求规格说明书（本文档的第\ref{section:xuqiufenxi}部分）。

通过需求规格说明书，我们有效地加快了程序设计和代码编写的过程，提升了程序架构和代码的质量。


\subsection{项目测试}
在项目的最终测试阶段，为了对Dao层接口进行测试，我们编写了一个测试程序，
进行了黑盒测试。该测试程序覆盖了每个接口类的每个接口函数可能的大部分输入情况，极大地提高了测试效率。
通过这个测试程序，我们成功发现并修复了多个bug，最终得到了经过充分测试的稳定可靠的程序。









